package com.dingreading.cloud.subject.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.subject.dto.SubjectLessonListDto;
import com.dingreading.cloud.subject.dto.SubjectLessonVideoDto;
import com.dingreading.cloud.subject.dto.SubjectsFileDto;
import com.dingreading.cloud.subject.entity.Subjects;
import com.dingreading.cloud.subject.entity.SubjectsFiles;
import com.dingreading.cloud.subject.service.*;
import com.dingreading.cloud.subject.util.CdnUrlUtil;
import com.dingreading.cloud.subject.util.TreeJsonUtil;
import com.dingreading.cloud.subject.util.redis.RedisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/front/subjects/v2")
@Api(tags = "门店-学科管理V2")
public class FrontSubjectsControllerV2 {

    @Resource
    private SubjectsService subjectsService;
    @Resource
    private StaffService staffService;
    @Resource
    private SubjectsFilesService subjectsFilesService;
    @Resource
    private SubjectLessonService subjectLessonService;
    @Resource
    private StoresService storesService;
    @Resource
    private RedisService redisService;
    @Resource
    private CdnUrlUtil cdnUrlUtil;


    @ApiOperation(value = "获取主科目列表")
    @PostMapping(value = "/getMainSubjects")
    public R<Object> getMainSubjects(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName
    ) {
        // 运营类型是产品加盟，则筛选学科
        List<Long> subjectIdList = storesService.getSubjectIdList(storeUid);
        if (CollectionUtils.isEmpty(subjectIdList))
            return R.fail("门店未分配科目，请联系运营人员");

        // 员工账号自定义学科权限
        String subjectType = staffService.getSubjectType(staffUid);
        if (StringUtils.isNotBlank(subjectType)) {
            Set<Long> staffSubjectIdSet = Arrays.stream(subjectType.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .map(Long::parseLong)
                    .collect(Collectors.toSet());

            subjectIdList = subjectIdList.stream()
                    .filter(staffSubjectIdSet::contains)
                    .collect(Collectors.toList());
        }

        List<Subjects> list = subjectsService.getMainSubjectsV3(subjectIdList);

        // 防止备课系统在鉴权文件时会同时大量验证登录权限，提前缓存鉴权登录用户信息
        preprocessAuth(request);
        return R.ok(list);
    }


    @ApiOperation(value = "获取下级科目列表")
    @PostMapping(value = "/getChildSubjects")
    public R<Object> getChildSubjects(
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "主科目id") @RequestParam(value = "mainId") Long mainId
    ) {
        JSONArray treeJson = new JSONArray();
        String redisKey = RedisParam.CHILD_SUBJECT + mainId;

        String json = (String) redisService.get(redisKey);

        if (StringUtils.isNotBlank(json)) {
            // 获取redis缓存数据
            treeJson = JSONArray.parseArray(json);
        } else {
            List<Subjects> list = subjectsService.getChildSubjectsV2(mainId);
            if (CollectionUtils.isNotEmpty(list)) {
                for (Subjects subjects : list) {
                    List<SubjectsFiles> files = subjectsFilesService.getFilesBySubjectId(subjects.getId());
                    JSONObject jsonObject = JsonUtil.toJsonObject(subjects);
                    if (subjects.getLevelIndex().equals(1)) {
                        jsonObject.put("childList", TreeJsonUtil.fromTree(subjects, list));
                        jsonObject.put("entranceTest", files);
                        treeJson.add(jsonObject);
                    }
                }

                // 缓存半小时
                redisService.set(redisKey, treeJson.toJSONString(), 1800);
            }
        }

        return R.ok(treeJson);
    }


    @ApiOperation(value = "获取学科下的课次列表")
    @PostMapping(value = "/getSubjectLessons")
    public R<Object> getSubjectLessons(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "学科id") @RequestParam(value = "subjectId") Long subjectId
    ) {
        Subjects subjects = subjectsService.getById(subjectId);
        if (subjects == null) return R.fail("学科获取失败");
        if (!subjects.getEnabled().equals(1)) return R.fail("学科已被禁用");
        if (!subjects.getLevelEnd().equals(1)) return R.fail("学科不是最后一级");

        long power = 0;
        if (subjects.getFreeStatus() != null && subjects.getFreeStatus().equals(1)) {
            // 是体验学科并且是体验账号，则有权限
            power = 1;
        } else {
            // 非体验学科并且不是体验账号，则有权限
            if (!AccountUtil.isTyUser(corpUid)) {
                power = 1;
            }
        }
        List<SubjectsFiles> files = subjectsFilesService.getFilesBySubjectId(subjectId);

        List<SubjectLessonListDto> lessonList = subjectLessonService.getSubjectLessonNoUrl(subjectId);
        if (CollectionUtils.isNotEmpty(lessonList)) {
            for (SubjectLessonListDto lessonDto : lessonList) {
                lessonDto.setPower(power);
                if (power != 1)
                    lessonDto.setDataUrl(null);
                boolean b = lessonDto.getDownloadStatus() != null;
                lessonDto.setDownloadStatus(b);

                List<SubjectLessonVideoDto> videoList = lessonDto.getVideoList();
                if (CollectionUtils.isNotEmpty(videoList)) {
                    Boolean speakVideoStatus = videoList.stream()
                            .anyMatch(video -> video.getVideoType() != null && video.getVideoType() == 0);
                    lessonDto.setSpeakVideoStatus(speakVideoStatus);

                    Boolean teachVideoStatus = videoList.stream()
                            .anyMatch(video -> video.getVideoType() != null && video.getVideoType() == 1);
                    lessonDto.setTeachVideoStatus(teachVideoStatus);
                }
            }
        }
        if (StringUtils.isNotBlank(subjects.getBookImg())) {
            R<String> r = cdnUrlUtil.getCdnUrl(request, subjects.getBookImg());
            if (R.isError(r)) {
                return R.fail(r.getMsg());
            }
            String bookImgCdnUrl = r.getData();
            subjects.setBookImg(bookImgCdnUrl);
        }
        if (StringUtils.isNotBlank(subjects.getVideoUrl())) {
            R<String> r = cdnUrlUtil.getCdnUrl(request, subjects.getVideoUrl());
            if (R.isError(r)) {
                return R.fail(r.getMsg());
            }
            String videoUrlCdnUrl = r.getData();
            subjects.setVideoUrl(videoUrlCdnUrl);
        }

        JSONObject jsonObject = new JSONObject();
        ArrayList<SubjectsFiles> subjectsTeachFiles = new ArrayList<>();
        ArrayList<SubjectsFiles> subjectsReadFiles = new ArrayList<>();
        ArrayList<SubjectsFiles> subjectsDownloadFiles = new ArrayList<>();
        ArrayList<SubjectsFiles> subjectsBookPreviewFiles = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(files)) {
            for (SubjectsFiles file : files) {
                if (file.getFileType().equals(0)) {
                    subjectsTeachFiles.add(file);
                } else if (file.getFileType().equals(1)) {
                    subjectsReadFiles.add(file);
                } else if (file.getFileType().equals(2)) {
                    subjectsDownloadFiles.add(file);
                } else if (file.getFileType().equals(3)) {
                    subjectsBookPreviewFiles.add(file);
                }
            }
        }
        jsonObject.put("teachFiles", subjectsTeachFiles);
        jsonObject.put("readFiles", subjectsReadFiles);
        jsonObject.put("downloadFiles", subjectsDownloadFiles);
        jsonObject.put("bookPreviewFiles", subjectsBookPreviewFiles);
        jsonObject.put("subjects", subjects);
        jsonObject.put("subjectLesson", lessonList);
        return R.ok(jsonObject);
    }


    @ApiOperation(value = "获取学科下的课次列表new")
    @PostMapping(value = "/getSubjectLessonList")
    public R<Object> getSubjectLessonList(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "学科id") @RequestParam(value = "subjectId") Long subjectId
    ) {
        Subjects subjects = subjectsService.getById(subjectId);
        if (subjects == null) return R.fail("学科获取失败");
        if (!subjects.getEnabled().equals(1)) return R.fail("学科已被禁用");
        if (!subjects.getLevelEnd().equals(1)) return R.fail("学科不是最后一级");

        long power = 0;
        if (subjects.getFreeStatus() != null && subjects.getFreeStatus().equals(1)) {
            // 是体验学科并且是体验账号，则有权限
            power = 1;
        } else {
            // 非体验学科并且不是体验账号，则有权限
            if (!AccountUtil.isTyUser(corpUid)) {
                power = 1;
            }
        }

        List<SubjectLessonListDto> lessonList = subjectLessonService.getSubjectLessonNoUrl(subjectId);
        if (CollectionUtils.isNotEmpty(lessonList)) {
            for (SubjectLessonListDto lessonDto : lessonList) {
                lessonDto.setPower(power);
                if (power != 1)
                    lessonDto.setDataUrl(null);
                boolean b = lessonDto.getDownloadStatus() != null;
                lessonDto.setDownloadStatus(b);

                List<SubjectLessonVideoDto> videoList = lessonDto.getVideoList();
                if (CollectionUtils.isNotEmpty(videoList)) {
                    Boolean speakVideoStatus = videoList.stream()
                            .anyMatch(video -> video.getVideoType() != null && video.getVideoType() == 0);
                    lessonDto.setSpeakVideoStatus(speakVideoStatus);

                    Boolean teachVideoStatus = videoList.stream()
                            .anyMatch(video -> video.getVideoType() != null && video.getVideoType() == 1);
                    lessonDto.setTeachVideoStatus(teachVideoStatus);
                }
            }
        }
        if (StringUtils.isNotBlank(subjects.getBookImg())) {
            R<String> r = cdnUrlUtil.getCdnUrl(request, subjects.getBookImg());
            if (R.isError(r)) {
                return R.fail(r.getMsg());
            }
            String bookImgCdnUrl = r.getData();
            subjects.setBookImg(bookImgCdnUrl);
        }

        List<SubjectsFileDto> fileList = subjectsFilesService.dtoListBySubjectId(subjectId);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("subjectLesson", lessonList);
        jsonObject.put("subjectFileList", fileList);
        return R.ok(jsonObject);
    }

    @ApiOperation(value = "获取备课文件的访问地址")
    @PostMapping(value = "/getDownloadUrl")
    public R<Object> getDownloadUrl(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "下载文件id") @RequestParam(value = "id") Long id
    ) {
        return subjectsService.getDownloadUrl(request, corpUid, storeUid, storeName, staffUid, staffName, id);
    }

    @ApiOperation(value = "获取备课文件的信息")
    @PostMapping(value = "/getSubjectFile")
    public R<Object> getSubjectFile(
            HttpServletRequest request,
            @ApiParam(value = "公司uid") @RequestParam(value = "corpUid") String corpUid,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "门店名称") @RequestParam(value = "storeName") String storeName,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "员工姓名") @RequestParam(value = "staffName") String staffName,
            @ApiParam(value = "下载文件id") @RequestParam(value = "id") Long id
    ) {
        return subjectsService.getSubjectFile(request, corpUid, storeUid, storeName, staffUid, staffName, id);
    }


    /**
     * 防止备课系统在鉴权文件时会同时大量验证登录权限，提前缓存鉴权登录用户信息
     */
    private void preprocessAuth(HttpServletRequest request) {
        CompletableFuture.supplyAsync(() -> {
            Cookie cookie = CookiesUtil.getCookieByName(request, LoginAuthUtil.DDPB_TOKEN);
            if (cookie == null || StringUtils.isBlank(cookie.getValue())) {
                // 获取cookieValue失败
                return "";
            } else {
                // 提前缓存鉴权登录用户信息
                String ip = IpUtil.getIpAddr(request);
                String cookieValue = cookie.getValue();
                Map<String, String> map = new HashMap<>();
                map.put("cookieValue", cookieValue);
                map.put("ip", ip);
                HttpUtils.post("https://lesson.dingreading.com/reqt/front/subjects/preprocessAuth", map);
            }
            return "";
        }).exceptionally(ex -> "").handle((result, ex) -> "");
    }


    /*// 课件index.html输出时添加script，监听上下箭头，解决翻页笔对应不同的键盘按钮
    private final static String script = "<script>window.onkeydown = function(e) {if(e && e.keyCode == 38) {e.preventDefault();var r= new KeyboardEvent('keydown',{'keyCode':33,'which':33});document.dispatchEvent(r);};if(e && e.keyCode == 40 ) {e.preventDefault();var d = new KeyboardEvent('keydown',{'keyCode':34,'which':34});document.dispatchEvent(d);};};</script>";

    String errorHtmlUrl = "/home/subject/error.html";
    String errorPdfUrl = "/home/subject/error.pdf";

    @ApiOperation(value = "验证用户权限接口")
    @GetMapping(value = "/auth")
    public void auth(
            HttpServletRequest request,
            HttpServletResponse response,
            @ApiParam(value = "参数") @RequestParam(value = "path") String path
    ) {
//        System.out.println("验证接口 = \n" + path);

        // 验证用户权限...
        File file = null;
        String address = "";
        // path地址正确
        if (path.indexOf(".") > 0) {
            boolean power = true;

            // 根据文件类型设置contentType
            List<String> list = Arrays.stream(path.split("\\.")).collect(Collectors.toList());
            String fileType = list.get(1);

            if (power) {
                // 权限通过
                // url地址转文件流
//            address = "https://test.dingreading.com/authed/subject/wxs/1/index.html";
//            URL url = null;
//            try {
//                url = new URL(address);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//            File file = urlToFile(url);

                // 本机文件地址转文件流
//                address = "C:\\Users\\Administrator\\Desktop\\2\\index.html";
//                address = "C:\\Users\\Administrator\\Desktop\\zhuangzi.pdf";
//                address = "C:\\Users\\Administrator\\Desktop\\1.png";

                // linux文件地址转文件流
//                address = "/home/subject/wxs/1/index.html";
                address = "/home/" + path;
                file = new File(address);
            } else {
                if (fileType.equalsIgnoreCase("pdf")) {
                    file = new File(errorPdfUrl);
                } else {
                    file = new File(errorHtmlUrl);
                }
            }

            if (!file.exists()) {
                // 未找到文件返回错误页或pdf
                if (fileType.equalsIgnoreCase("pdf")) {
                    file = new File(errorPdfUrl);
                } else {
                    file = new File(errorHtmlUrl);
                }
            }
            // 设置contentType
            if (fileType.equalsIgnoreCase("html")) {
                response.setContentType("text/html");
                response.setCharacterEncoding("UTF-8");
            } else if (fileType.equalsIgnoreCase("png")) {
                response.setContentType("image/png");
            } else if (fileType.equalsIgnoreCase("jpg")) {
                response.setContentType("image/png");
            } else if (fileType.equalsIgnoreCase("jpeg")) {
                response.setContentType("image/png");
            } else if (fileType.equalsIgnoreCase("gif")) {
                response.setContentType("image/gif");
            } else if (fileType.equalsIgnoreCase("pdf")) {
                response.setContentType("application/pdf");
            } else {

            }
        }

        // 将文件输出到页面
        ServletOutputStream out = null;
        try {
            FileInputStream inputStream = new FileInputStream(file);
            out = response.getOutputStream();
            int b = 0;
            byte[] buffer = new byte[1024];
            while ((b = inputStream.read(buffer)) != -1) {
                // 4.写到输出流(out)中
                out.write(buffer, 0, b);
            }
            if (path.contains("index.html")) {
                out.write(script.getBytes("UTF-8"));
            }
            inputStream.close();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }*/

}